import React, { Component } from 'react';
import { graphql, compose } from 'react-apollo';
import gql from 'graphql-tag';
import { Vibration, Text, View, StyleSheet, Alert, ScrollView, ActivityIndicator } from 'react-native';
import { Icon, List, ListItem, Button, SearchBar } from 'react-native-elements';
import update from 'immutability-helper';
import Loader from './widgets/Loader';
import { clearStorage } from './clientStorage';
import { NavigationActions } from 'react-navigation';
import { screenWidth, toast, primaryColor, executor, isIOS } from './utils';
import Camera from 'react-native-camera';
import { BagCheckQuery } from './graphql';
import moment from 'moment';

const styles = StyleSheet.create({
  button: {
    marginTop: 16
  },
  container: {
    flex: 1,
    flexDirection: 'row',
  },
  preview: {
    flex: 1,
    justifyContent: 'flex-end',
    height: screenWidth/2,
    alignItems: 'center',
    position: 'relative',
  },
  capture: {
    flex: 0,
    backgroundColor: '#fff',
    borderRadius: 5,
    color: '#000',
    padding: 10,
    margin: 40
  },
  text: {
    borderWidth: 4,
    borderColor: 'gray',
    position: 'absolute',
    top: screenWidth/6,
    bottom: screenWidth/6,
    left: 6,
    right: 6,
    justifyContent: 'center',
    alignItems: 'center'
  }
});

class BagScanPage extends Component {
  static navigationOptions = ({navigation}) => {
    return {
      title: navigation.state.params.assignOrder?`Assign Order`:`Order #${navigation.state.params.displayId}`,
    };
  }
  state = {laundryBags:[]}
  componentDidMount() {
    if (this.props.navigation.state.params.laundryBags) {
      this.setState({laundryBags: this.props.navigation.state.params.laundryBags});
    }
  }
  componentWillReceiveProps(nextProps) {
    if (nextProps.navigation.state.params.orderNumber&&
      (nextProps.navigation.state.params.orderNumber!==this.props.navigation.state.params.orderNumber)) {
      Vibration.vibrate();
      executor(this.props.selfAssignOrder, nextProps.navigation.state.params.orderNumber)
        .then(({res}) => {
          if (res&&res.selfAssignOrder) {
            toast(`Order #${nextProps.navigation.state.params.orderNumber} already assign to you`);

            this.props.navigation.dispatch(NavigationActions.reset({
              index: 1,
              actions: [
                NavigationActions.navigate({routeName: 'Main'}),
                NavigationActions.navigate({routeName: 'OrderDetail', params: {displayId: res.selfAssignOrder.displayId, id: res.selfAssignOrder.id}}),
              ]
            }));
          }
          this.setState({submitting: false});
        });
      this.setState({submitting: true});
      toast(`Assigning order #${nextProps.navigation.state.params.orderNumber}`, true);
    }
  }
  onInput = (data) => this.handleBarCodeRead({data})
  handleBarCodeRead = ({data}) => {
    if (this.props.navigation.state.params.assignOrder) {
      if (data&&!isNaN(data)) {
        this.onAssign(parseInt(data));
      }
    } else {
      const bagNumber = data&&data.toUpperCase().indexOf('KK')===0&&data.length===6&&data.toUpperCase();
      if (bagNumber&&(this.state.laundryBags.indexOf(bagNumber)<0)) {
        Vibration.vibrate();
        toast(`Bag ${bagNumber} added`);
        this.setState({laundryBags: [...this.state.laundryBags, bagNumber], input: ''});
      } else {
        this.setState({input: data});
      }
    }
  }
  onAssign = (orderNumber) => {
    this.props.navigation.setParams({orderNumber});
  }
  onSubmit = () => {
    if (this.state.laundryBags.length===0) return toast(`Please scan laundry bag`);

    executor(this.props.navigation.state.params.update?this.props.updateLaundryBags:this.props.confirmPickup,
      this.state.laundryBags)
      .then(({res}) => {
        if (res) {
          toast('Success');
          this.props.navigation.goBack();
        }
        this.setState({submitting: false});
      });
    this.setState({submitting: true});
  }
  render() {
    const { input, assignOrder } = this.props.navigation.state.params;

    return (
      <ScrollView>
        <View style={styles.container}>
          <Camera onBarCodeRead={this.handleBarCodeRead} {...(isIOS()?{}:{barCodeTypes:['code128']})}
            style={styles.preview} torchMode={Camera.constants.TorchMode.auto}
            aspect={Camera.constants.Aspect.fill}>
            <View style={styles.text}><Text style={{color:'gray',backgroundColor:'transparent',fontSize:26,textAlign:'center'}}>Match barcode to this width</Text></View>
          </Camera>
        </View>
        {input&&
          <SearchBar inputStyle={{height:50}} value={this.state.input} placeholder='Input bag number' lightTheme onChangeText={this.onInput}/>
        }
        {!assignOrder&&
          <List>
            {
              this.state.laundryBags.map((bag, index) => <ListItem key={index} title={bag}
                subtitle='Laundry Bag' rightIcon={{name:'clear'}} onPress={() => {
                  const index = this.state.laundryBags.indexOf(bag);
                  this.setState({laundryBags: [...this.state.laundryBags.slice(0,index), ...this.state.laundryBags.slice(index+1)]});
                }}/>)
            }
          </List>
        }
        {this.state.submitting?<ActivityIndicator style={styles.button}/>:(!assignOrder&&
          <View style={styles.button}>
            <Button title='SUBMIT' backgroundColor={primaryColor} onPress={this.onSubmit}/>
          </View>
        )}
      </ScrollView>
    );
  }
}

export default compose(
  graphql(gql`
    mutation confirmPickup($orderId:String!,$laundryBags:[String]) {
      confirmPickup(orderId:$orderId,laundryBags:$laundryBags) {
        id
        status {
          statusId
          displayStatus
        }
      }
    }
  `, {
    name: 'confirmPickup',
    props: ({ownProps:{navigation:{state:{params:{id}}}}, confirmPickup}) => {
      return {
        confirmPickup: (laundryBags) => confirmPickup({
          variables:{orderId:id,laundryBags},
          updateQueries: {
            OrderList: (prev, { mutationResult }) => {
              const completeOrder = mutationResult.data.confirmPickup;
              const index = prev.orders.findIndex(item => item.id===completeOrder.id);

              if (index >= 0) {
                return update(prev, {
                  orders: {
                    $splice: [[index,1]]
                  }
                });
              } else {
                return prev;
              }
            },
          }
        })
      };
    }
  }),
  graphql(gql`
    mutation updateLaundryBags($orderId:String!,$laundryBags:[String]) {
      updateLaundryBags(orderId:$orderId,laundryBags:$laundryBags) {
        id
        status {
          statusId
        }
      }
    }
  `, {
    name: 'updateLaundryBags',
    props: ({ownProps:{navigation:{state:{params:{id, date}}}}, updateLaundryBags}) => {
      return {
        updateLaundryBags: (laundryBags) => updateLaundryBags({
          variables:{orderId:id,laundryBags},
          refetchQueries: [{
            query: BagCheckQuery,
            variables: { 
              date: date||moment([moment().year(), moment().month(), moment().date()]).subtract(1,'days').toDate().toString()
            },
          }]
        })
      };
    }
  }),
  graphql(gql`
    mutation selfAssignOrder($orderNumber:Int!) {
      selfAssignOrder(orderNumber:$orderNumber) {
        id
        displayId
      }
    }
  `, {
    name: 'selfAssignOrder',
    props: ({selfAssignOrder}) => {
      return {
        selfAssignOrder: (orderNumber) => selfAssignOrder({variables:{orderNumber}})
      };
    }
  })
)(BagScanPage);

